package cate.game.activity.lottery;

import cate.common.table.activity.lottery.row.LotteryBaseRow;
import cate.common.table.activity.lottery.row.LotteryDrawRewardRow;
import cate.common.table.activity.lottery.row.LotteryRewardPoolRow;
import cate.common.table.d.GDOperation;
import cate.common.table.d.GDTreasureTurntable;
import cate.common.util.GameResult;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.lottery.data.LotteryLog;
import cate.game.activity.lottery.data.LotteryLogDetail;
import cate.game.activity.lottery.msg.DrawLotteryResp;
import cate.game.activity.lottery.msg.LotteryInfoResp;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.res.MixResItem;
import cate.game.role.Role;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LotteryActivity extends RoleActivitySingle {
    @NoteField("保底抽奖次数")
    public int drawTimes;
    @NoteField("累计抽奖次数")
    public int historyDrawTimes;

    @NoteField("免费抽奖剩余次数")
    public int freeTimes;

    @NoteField("个人抽奖记录")
    public LotteryLog selfLog;

    @NoteField("次数奖励领取记录")
    public Map<Integer, Boolean> numRewardMap;

    @NoteField("钻石抽奖已抽次数")
    public int diaTimes;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (numRewardMap == null) {
            numRewardMap = new HashMap<>();
        }
        if (selfLog == null) {
            selfLog = new LotteryLog();
        }
        selfLog.initialize();
    }

    /**
     * 全服记录
     * @return
     */
    public LotteryLog getZoneLog() {
        LotteryLog zoneLog = role.getGame().res.lottery.data.log;
        return zoneLog;
    }


    @Override
    public void onRoleOpen() {
        LotteryBaseRow baseRow = showBaseRow();
        if (baseRow == null) {
            return;
        }
        this.freeTimes = baseRow.freeLimit;
    }

    @Override
    public void onRoleEnd() {
        drawTimes = 0;
        freeTimes = 0;
        diaTimes = 0;
        historyDrawTimes = 0;
        numRewardMap.clear();
        selfLog = null;
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    @Override
    public void excelCheck() {
        LotteryBaseRow baseRow = showBaseRow();
        if (baseRow == null) {
            return;
        }
        numRewardMap.entrySet().removeIf(entry -> role.getGame().table.lottery.times.get(entry.getKey()) == null);
        for (LotteryDrawRewardRow row : role.getGame().table.lottery.times.getList()) {
            if (row.group == baseRow.timesGroup) {
                if (!numRewardMap.containsKey(row.id)) {
                    numRewardMap.put(row.id, false);
                }
            }
        }
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        if (!enable()) {
            return;
        }
        LotteryBaseRow baseRow = showBaseRow();
        if (baseRow == null) {
            return;
        }
        this.freeTimes = baseRow.freeLimit;
        this.diaTimes = 0;
        noticeUpdate();
    }

    /**
     * 单抽
     * @return
     */
    public GameResult<LotteryActivity> singleDraw() {
        GameResult<LotteryActivity> r = new GameResult<>();
        LotteryBaseRow baseRow = showBaseRow();
        if (baseRow == null) {
            return r.fail("活动配置不存在");
        }
        MixRes cost = new MixRes(baseRow.oneCost);
        boolean isFree = false;
        //免费抽
        if (freeTimes > 0) {
            freeTimes --;
            isFree = true;
        } else {
            if (StringUtils.isBlank(baseRow.oneCost)) {
                return r.fail("消耗未配置");
            }
            //道具消耗

            GameResult<MixResItem> consume = cost.consumeCheck(role);
            if (!consume.ok()) {
                /*if (diaTimes >= 20 ) {
                    return r.fail("钻石抽奖次数已达上限");
                }*/
                //钻石消耗
                cost = new MixRes(baseRow.oneDiaCost);
                GameResult<MixResItem> consumeDia = cost.consumeCheck(role);
                if (!consumeDia.ok()) {
                    return r.fail(consumeDia);
                }
                diaTimes ++;
            }
        }
        r = draw(1, baseRow);
        if (r.ok() && !isFree ) {
            cost.consume(role);
        }
        return r;
    }

    public GameResult<LotteryActivity> tenDraw() {
        GameResult<LotteryActivity> r = new GameResult<>();
        LotteryBaseRow baseRow = showBaseRow();
        if (baseRow == null) {
            return r.fail("活动配置不存在");
        }
        if (StringUtils.isBlank(baseRow.tenCost)) {
            return r.fail("消耗未配置");
        }
        //道具消耗
        MixRes cost = new MixRes(baseRow.tenCost);
        GameResult<MixResItem> consume = cost.consumeCheck(role);
        if (!consume.ok()) {
            //暂时不要
            /*if (diaTimes >= 20 || ((diaTimes + 10) > 20 )) {
                return r.fail("钻石抽奖次数已达上限");
            }*/
            //钻石消耗
            cost = new MixRes(baseRow.tenDiaCost);
            GameResult<MixResItem> consumeDia = cost.consumeCheck(role);
            if (!consumeDia.ok()) {
                return r.fail(consumeDia);
            }
            diaTimes += 10;
        }
        r = draw(10, baseRow);
        if (r.ok()) {
            cost.consume(role);
        }
        return r;
    }

    /**
     * 随机抽奖
     * @param times
     * @param baseRow
     * @return
     */
    private GameResult<LotteryActivity> draw(int times, LotteryBaseRow baseRow) {
        GameResult<LotteryActivity> r = new GameResult<>();
        MixRes rewards = new MixRes();
        List<MixRes> rewardShow = new ArrayList<>();
        for (int i = 0; i < times; i++) {
            LotteryRewardPoolRow row = role.getGame().table.lottery.pool.randomPool(baseRow.normalGroup);
            if (row == null) {
                return r.fail("奖励池不存在");
            }
            if (drawTimes >= baseRow.cheatTimes) {
                //达到保底次数
                row = role.getGame().table.lottery.pool.randomPool(baseRow.cheatGroup);
                if (row == null) {
                    return r.fail("保底奖励池不存在");
                }
                drawTimes = 0;
            } else {
                drawTimes++;
            }
            rewards.addList(new MixRes(row.reward));
            rewardShow.add(new MixRes(row.reward));
            historyDrawTimes++;
            addToLog(new MixRes(row.reward));
        }

        EcResult<?> exe = new MixResAdder().setRes(rewards)
                .setOperation(GDOperation.LOTTERY)
                .setDialogReward(false)
                .setSendMailWhenFull(true)
                .exe(role);
        DrawLotteryResp resp = new DrawLotteryResp(rewardShow);
        resp.sendNow(role);
        noticeUpdate();
        role.getHistory().action.drawLottery(times);
        return r;
    }

    /**
     * 增加抽奖记录
     */
    private void addToLog(MixRes reward) {
        LotteryLogDetail logDetail = new LotteryLogDetail(role.getBase().name, reward);
        addSelfLog(logDetail);
        role.getGame().res.lottery.addLog(logDetail);
    }

    /**
     * 个人抽奖记录
     * @param logDetail
     */
    private void addSelfLog(LotteryLogDetail logDetail) {
        selfLog.addLog(logDetail, GDTreasureTurntable.LOG_SIZE);
    }


    private LotteryBaseRow showBaseRow() {
        LotteryBaseRow row = role.getGame().table.lottery.base.get(configTid());
        return row;
    }

    private LotteryDrawRewardRow showDrawRewardRow(int tid) {
        return role.getGame().table.lottery.times.get(tid);
    }

    public void noticeUpdate() {
        role.sendNow(new LotteryInfoResp(this));
    }

    /**
     * 领取次数奖励
     * @param tid
     * @return
     */
    public GameResult<LotteryActivity> takeTimesReward(int tid) {
        GameResult<LotteryActivity> r = new GameResult<>();
        LotteryBaseRow baseRow = showBaseRow();
        if (baseRow == null) {
            return r.fail("活动配置不存在");
        }
        LotteryDrawRewardRow row = showDrawRewardRow(tid);
        if (row == null || !numRewardMap.containsKey(tid)) {
            return r.fail("奖励配置不存在");
        }
        if (numRewardMap.get(tid)) {
            return r.fail("奖励已领取");
        }
        if (historyDrawTimes < row.times) {
            return r.fail("抽奖次数不足");
        }
        MixRes res = new MixRes(row.reward);
        EcResult<?> exe = new MixResAdder().setRes(res)
                .setOperation(GDOperation.LOTTERY)
                .setDialogReward(true)
                .setSendMailWhenFull(true)
                .exe(role);
        numRewardMap.put(tid, true);
        checkMapStatus();
        noticeUpdate();
        return r;
    }

    /**
     * 累计次数重置检查
     */
    private void checkMapStatus() {
        boolean check = true;
        for(boolean rewardAll : numRewardMap.values()) {
            if (!rewardAll) {
                check = false;
            }
        }
        if (check) {
            LotteryBaseRow baseRow = showBaseRow();
            if (baseRow == null) {
                return;
            }
            numRewardMap = new HashMap<>();
            int maxScore = 0;
            for (LotteryDrawRewardRow row : role.getGame().table.lottery.times.getList()) {
                if (row.group == baseRow.timesGroup) {
                    numRewardMap.put(row.id, false);
                    maxScore = Math.max(maxScore, row.times);
                }
            }
            historyDrawTimes -= maxScore;
        }
    }
}
